/*
 *  Jajuk
 *  Copyright (C) 2003-2008 The Jajuk Team
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *  $Revision: 3132 $
 */
package aspecto;

import java.util.Iterator;

import org.aspectj.lang.SoftException;
import org.jajuk.services.reporting.ExporterFactory;
import org.jajuk.base.*;
import org.jajuk.services.dj.*;
import org.jajuk.util.*;
import org.jajuk.services.reporting.*;
import org.jajuk.util.log.*;

import java.util.*;

/**
 * 
 */
privileged public aspect toXMLAspect {
  
  /**
   * Return an XML representation of this item
   * 
   * @return
   */
  /**
   * @return
   */
/*  public String Item.toXml() {
    try {
      StringBuilder sb = new StringBuilder("\t\t<").append(getLabel());
      sb.append(getPropertiesXml());
      sb.append("/>\n");
      return sb.toString();
    } catch (Exception e) {
      // catch any error here because it can prevent
      // collection to commit
      Log.error(e);
      return "";
    }
  }*/
  
  /**
   * 
   * @return XML representation of this manager
   */
  public String ItemManager.toXML() {
    StringBuilder sb = new StringBuilder("\t<").append(getLabel() + ">");
    Iterator<String> it = hmPropertiesMetaInformation.keySet().iterator();
    while (it.hasNext()) {
      String sProperty = it.next();
      PropertyMetaInformation meta = hmPropertiesMetaInformation.get(sProperty);
      sb.append('\n' + meta.toXML());
    }
    return sb.append('\n').toString();
  }
  
  public String PropertyMetaInformation.toXML() {
    String sDefault = "";
    try {
      if (oDefaultValue != null) {
        sDefault = Util.format(oDefaultValue, this, false);
      }
    } catch (Exception e) { // should to occur at this point
      Log.error(e);
    }
    return "\t\t<" + XML_PROPERTY + " " + XML_NAME + "='" + Util.formatXML(sName) + "' "
        + XML_CUSTOM + "='" + bCustom + "' " + XML_CONSTRUCTOR + "='" + bConstructor + "' "
        + XML_VISIBLE + "='" + bShouldBeDisplayed + "' " + XML_EDITABLE + "='" + bEditable + "' "
        + XML_UNIQUE + "='" + bMergeable + "' " + XML_TYPE + "='" + cType.getName() + "' "
        + XML_DEFAULT_VALUE + "='" + Util.formatXML(sDefault) + "'/>";
  }
  
  public String Ambience.toXML() {
    String s = "";
    for (Style style : getStyles()) {
      s += style.getID() + ",";
    }
    return s.substring(0, s.length() - 1); // remove last coma
  }
  
  public String AmbienceDigitalDJ.toXML() {
    StringBuilder sb = new StringBuilder(2000);
    sb.append(toXMLGeneralParameters());
    sb.append("\t<" + XML_DJ_AMBIENCE + " " + XML_DJ_VALUE + "='");
    sb.append(ambience.getID() + "'/>\n");
    sb.append("</" + XML_DJ_DJ + ">\n");
    return sb.toString();
  }
  
  abstract public String DigitalDJ.toXML();
  
  public String DigitalDJ.toXMLGeneralParameters() {
    StringBuilder sb = new StringBuilder();
    sb.append("<?xml version='1.0' encoding='UTF-8'?>\n");
    sb.append("<" + XML_DJ_DJ + " " + XML_VERSION + "='" + JAJUK_VERSION + "' " + XML_ID + "='"
        + sID + "' " + XML_NAME + "='" + sName + "' " + XML_TYPE + "='" + this.getClass().getName()
        + "'>\n");
    sb.append("\t<" + XML_DJ_GENERAL + " ");
    sb.append(XML_DJ_RATING_LEVEL + "='" + iRatingLevel + "' ");
    sb.append(XML_DJ_UNICITY + "='" + bUnicity + "' ");
    sb.append(XML_DJ_FADE_DURATION + "='" + iFadingDuration + "'/>\n");
    return sb.toString();
  }
  
  public String ProportionDigitalDJ.toXML() {
    StringBuilder sb = new StringBuilder(2000);
    sb.append(toXMLGeneralParameters());
    sb.append("\t<" + XML_DJ_PROPORTIONS + ">\n");
    for (Proportion proportion : proportions) {
      String stylesDesc = "";
      for (Style style : proportion.getStyles()) {
        stylesDesc += style.getID() + ',';
      }
      // remove trailing coma
      stylesDesc = stylesDesc.substring(0, stylesDesc.length() - 1);
      sb.append("\t\t<" + XML_DJ_PROPORTION + " " + XML_DJ_STYLES + "='" + stylesDesc + "' "
          + XML_DJ_VALUE + "='" + proportion.getProportion() + "'/>\n");
    }
    sb.append("\t</" + XML_DJ_PROPORTIONS + ">\n");
    sb.append("</" + XML_DJ_DJ + ">\n");
    return sb.toString();
  }
  
  public String TransitionDigitalDJ.toXML() {
    StringBuilder sb = new StringBuilder(2000);
    sb.append(toXMLGeneralParameters());
    sb.append("\t<" + XML_DJ_TRANSITIONS + " " + XML_DJ_STARTUP_STYLE + "='"
        + getStartupStyle().getID() + "'>\n");
    for (Transition transition : transitions) {
      sb.append("\t\t<" + XML_DJ_TRANSITION + " " + XML_DJ_FROM + "='"
          + transition.getFrom().toXML() + "' " + XML_DJ_TO + "='" + transition.getTo().toXML()
          + "' " + XML_DJ_NUMBER + "='" + transition.getNbTracks() + "'/>\n");
    }
    sb.append("\t</" + XML_DJ_TRANSITIONS + ">\n");
    sb.append("</" + XML_DJ_DJ + ">\n");
    return sb.toString();
  }
  
  public String Item.toXml() {
    try {
      StringBuilder sb = new StringBuilder("\t\t<").append(getLabel());
      sb.append(getPropertiesXml());
      sb.append("/>\n");
      return sb.toString();
    } catch (Exception e) {
      // catch any error here because it can prevent
      // collection to commit
      Log.error(e);
      return "";
    }
  }
  
  public XMLExporter HTMLExporter.xmlExporter;
  
  pointcut processCollection(HTMLExporter exp) :
    execution(void HTMLExporter.processCollection(int)) && this(exp) ||
    execution(void HTMLExporter.process(ArrayList<Item>)) && this(exp);
  
 
  before(HTMLExporter exp) : processCollection(exp){
    // Get an instance of the XMLExporter.
    try {
      exp.xmlExporter = (XMLExporter) ExporterFactory.createExporter("xml");
    } catch (Exception e) {
      throw new SoftException(e);
    }
  }
  
  /**
   * 
   * @return XML representation for item properties
   */
  private String Item.getPropertiesXml() {
    StringBuilder sb = new StringBuilder();
    for (String sKey : properties.keySet()) {
      String sValue = null;
      Object oValue = properties.get(sKey);
      if (oValue != null) {
        PropertyMetaInformation meta = getMeta(sKey);
        try {
          sValue = Util.format(oValue, meta, false);
        } catch (Exception e) { // should not occur
          Log.error(e);
        }
        sValue = Util.formatXML(sValue); // make sure to remove
        // non-XML characters
      }
      sb.append(' ');
      sb.append(Util.formatXML(sKey));
      sb.append("='");
      sb.append(sValue);
      sb.append("'");
    }
    return sb.toString();
  }
}
